﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using Sita.MainModule.Services;
using Sita.Entities;
using Sita.Presentation.ViewModels;

namespace Sita.Presentation.Controllers
{
    public class InvoiceController : DefaultController
    {
        InvoiceService invoiceService;

        public InvoiceController()
        {
            invoiceService = new InvoiceService();
        }

        public ActionResult Index()
        {
            return View();
        }

        public PartialViewResult List(int? index, string sortColumn, bool? sortAscending, int? pageSize)
        {
            int TotalRows;

            int CurrentBusinessUnitID = this.AuthenticatedUser.Business[this.AuthenticatedUser.CurrentBusinessUnitIndex].BusinessUnitID;
            sortAscending = sortAscending ?? true;
            index = index ?? 0;
            if (string.IsNullOrEmpty(sortColumn))
                sortColumn = "InvoiceID";
            if (!pageSize.HasValue)
                pageSize = 5;

            ViewData["PageSizeFilter"] = new SelectList(new int[] { 5, 10, 15, 20 });

            return PartialView(
                    new GenericGridList<Invoice>(
                        invoiceService.GetPaginatedInvoicesByBussinesUnitID(CurrentBusinessUnitID, index.Value, pageSize.Value,
                        sortColumn, sortAscending.Value, out TotalRows), index.Value, sortColumn, pageSize.Value,
                        TotalRows, sortAscending.Value));
        }

        [HttpGet]
        public ActionResult CreateOrUpdate(int? id)
        {
            Invoice invoice;

            if (id.HasValue)
            {
                DeliveryNoteService deliveryNoteService = new DeliveryNoteService();
                invoice = invoiceService.GetInvoiceByIDWithItemsAndCustomer(id.Value);
                ViewData["CustomerName"] = invoice.Customer.CompanyName;
                ViewData["DeliveryNoteList"] = deliveryNoteService.GetAvailableDeliveryNotesByCustomerID(invoice.CustomerID);
                
            }
            else
            {
                invoice = new Invoice();
                ViewData["CustomerName"] = "";
                ViewData["DeliveryNoteList"] = null;
            }
            return View(invoice);
        }

        public JsonResult LockStock(int? id)
        {
            string Result;
            Dictionary<string, object> ResultDetails;
            ResultDetails = new Dictionary<string, object>();
            if (id.HasValue)
            {
                Result = invoiceService.ValidateStockAndLock(id.Value);

                if (Result == "SUCCESS")
                {
                    ResultDetails["Success"] = true;
                }
                else
                {
                    ResultDetails["Success"] = false;
                    ResultDetails["Message"] = Result;

                }

            }

            JsonResult Response = new JsonResult();
            Response.Data = ResultDetails;


            return Response;
        }

        [HttpPost]
        public JsonResult CreateOrUpdate(Invoice invoice)
        {
            Invoice currentInvoice;
            Invoice originalInvoice = null;

            currentInvoice = invoice;

            if (currentInvoice.InvoiceID == 0)
            {
                currentInvoice.BusinessUnitID = this.AuthenticatedUser.Business[this.AuthenticatedUser.CurrentBusinessUnitIndex].BusinessUnitID;
                invoiceService.AddInvoice(currentInvoice);
            }
            else
            {
                originalInvoice = invoiceService.GetInvoiceByIDWithItems(currentInvoice.InvoiceID);
                originalInvoice.CustomerID = currentInvoice.CustomerID;
                originalInvoice.CreationDate = currentInvoice.CreationDate;

                #region DeliveryNotes
                //Add new DeliveryNotes
                foreach (var deliveryNote in currentInvoice.InvoiceDeliveryNotes)
                {
                    if (originalInvoice.InvoiceDeliveryNotes.Where(dn => dn.DeliveryNoteID == deliveryNote.DeliveryNoteID).FirstOrDefault() == null)
                    {
                        originalInvoice.InvoiceDeliveryNotes.Add(new InvoiceDeliveryNote()
                        {
                            InvoiceID = currentInvoice.InvoiceID,
                            DeliveryNoteID = deliveryNote.DeliveryNoteID
                        });
                    }
                }
                //Remove DeliveryNotes that have been deleted
                foreach (var deliveryNote in originalInvoice.InvoiceDeliveryNotes.ToList())
                {
                    if (currentInvoice.InvoiceDeliveryNotes.Where(dn => dn.DeliveryNoteID == deliveryNote.DeliveryNoteID).FirstOrDefault() == null)
                    {
                        deliveryNote.MarkAsDeleted();
                    }
                }
                #endregion

                #region Replacements
                //Add new Replacements
                foreach (var replacement in currentInvoice.InvoiceReplacements)
                {
                    if (originalInvoice.InvoiceReplacements.Where(i => i.ReplacementID == replacement.ReplacementID && i.Quantity == replacement.Quantity && i.UnitPrice == replacement.UnitPrice && i.TotalPrice == replacement.TotalPrice).FirstOrDefault() == null)
                    {
                        originalInvoice.InvoiceReplacements.Add(new InvoiceReplacement()
                        {
                            InvoiceID = currentInvoice.InvoiceID,
                            ReplacementID = replacement.ReplacementID,
                            Quantity = replacement.Quantity,
                            UnitPrice = replacement.UnitPrice,
                            TotalPrice = replacement.TotalPrice
                        });
                    }
                }
                //Remove Replacements that have been deleted
                foreach (var replacement in originalInvoice.InvoiceReplacements.ToList())
                {
                    if (currentInvoice.InvoiceReplacements.Where(i => i.ReplacementID == replacement.ReplacementID && i.Quantity == replacement.Quantity && i.UnitPrice == replacement.UnitPrice && i.TotalPrice == replacement.TotalPrice).FirstOrDefault() == null)
                    {
                        replacement.MarkAsDeleted();
                    }
                }
                #endregion

                #region ExtraItems
                //Add new ExtraItems
                foreach (var extraItem in currentInvoice.InvoiceExtraItems)
                {
                    if (originalInvoice.InvoiceExtraItems.Where(ei => ei.Description == extraItem.Description && ei.Quantity == extraItem.Quantity && ei.UnitPrice == extraItem.UnitPrice && ei.TotalPrice == extraItem.TotalPrice).FirstOrDefault() == null)
                    {
                        originalInvoice.InvoiceExtraItems.Add(new InvoiceExtraItem()
                        {
                            InvoiceID = currentInvoice.InvoiceID,
                            Description = extraItem.Description,
                            Quantity = extraItem.Quantity,
                            UnitPrice = extraItem.UnitPrice,
                            TotalPrice = extraItem.TotalPrice
                        });
                    }
                }
                //Remove ExtraItems that have been deleted
                foreach (var extraItem in originalInvoice.InvoiceExtraItems.ToList())
                {
                    if (currentInvoice.InvoiceExtraItems.Where(ei => ei.Description == extraItem.Description && ei.Quantity == extraItem.Quantity && ei.UnitPrice == extraItem.UnitPrice && ei.TotalPrice == extraItem.TotalPrice).FirstOrDefault() == null)
                    {
                        extraItem.MarkAsDeleted();
                    }
                }
                #endregion

                invoiceService.ModifyInvoice(originalInvoice);
            }

            JsonResult Response = new JsonResult();
            Response.JsonRequestBehavior = JsonRequestBehavior.AllowGet;

            return Json(Response);
        }

        public ActionResult Print(int? id)
        {
            Invoice invoice = invoiceService.GetInvoiceByIDWithItemsAndCustomer(id.Value);
            return View(invoice);
        }
    }
}
